class Game {
  constructor(elem) {
    this.stage = new createjs.Stage(elem);
    this.playStatus = false;
    this.playerList = {};

    this.run();
    this.bindEvent();
  }

  bindEvent() {
    let prev = null;

    function action(key, flag) {
      let action = key + (flag ? '_up' : '');
      if (action == prev) return;
      app.action('game.action', {
        action
      });
      prev = action;
    }

    let event = {
      '0'(flag) {
        action('left', flag);
      },
      '1'(flag) {
        action('top', flag);
      },
      '2'(flag) {
        action('right', flag);
      },
      '3'(flag) {
        action('bottom', flag);
      },
      '-5'(flag){
        action('speed', flag);
      }
    }

    document.body.onkeydown = ev => {
      if (!this.playStatus) return;
      let code = ev.keyCode - 37;
      event[code] && event[code]();
    }
    document.body.onkeyup = ev => {
      if (!this.playStatus) return;
      let code = ev.keyCode - 37;
      event[code] && event[code](true);
    }
  }

  set(data) {
    this.data = data;
  }

  complite(action) {
    Object.keys(action).forEach(key => {
      action[key].forEach(ac => {
        this.playerList[key].action(ac);
      })
    });

    Object.keys(this.playerList).forEach(key => {
      this.playerList[key].move();
    })
  }

  run() {
    createjs.Ticker.timingMode = createjs.Ticker.RAF;
    createjs.Ticker.addEventListener('tick', () => {
      if (!this.playStatus) return;
      this.stage.update();
    });

    // 绘制初始地图
    let map = new createjs.Shape();
    map.graphics.beginStroke('red').drawCircle(600, 350,
      300);
    this.stage.addChild(map);
  }

  add(data) {
    this.playerList[data.id] = new Player(data);
    this.stage.addChild(this.playerList[data.id].container);
  }

  init() {
    this.playStatus = true;

  }
}

class Player {
  constructor(data) {
    this.data = data;
    this.x = 600;
    this.y = 350;
    this.moveX = 0;
    this.moveY = 0;
    this.speed = 10;
    this.speedAdd = 0;
    this.hX = 0;
    this.hY = 0;

    this.render();
  }

  render() {
    this.container = new createjs.Container();
    this.graph = new createjs.Shape();
    this.graph.graphics.beginFill(this.data.color).drawCircle(0, 0, 10);
    this.text = new createjs.Text(this.data.username, '14px Arial', 'white');
    this.text.x = -10;
    this.text.y = -25;
    this.container.addChild(this.graph);
    this.container.addChild(this.text);
    this.set();
  }

  action(action) {
    switch (action) {
      case 'left':
        this.moveX = -1;
        break;
      case 'left_up':
        this.moveX = 0;
        break;
      case 'right':
        this.moveX = 1;
        break;
      case 'right_up':
        this.moveX = 0;
        break;
      case 'top':
        this.moveY = -1;
        break;
      case 'top_up':
        this.moveY = 0;
        break;
      case 'bottom':
        this.moveY = 1;
        break;
      case 'bottom_up':
        this.moveY = 0;
        break;
      case 'speed':
        this.speedAdd = 1;
        break;
      case 'speed_up':
        this.speedAdd = 0;
        break;
    }
  }

  move() {
    let speedX = this.moveX * (this.speed + this.speedAdd * 30);
    let speedY = this.moveY * (this.speed + this.speedAdd * 30);
    this.x += speedX;
    this.y += speedY;

    if(speedY != 0){
      if((speedY > 0 && this.hY < 0) || (speedY < 0 && this.hY > 0)) this.hY = 0;
      this.hY += speedY > 0 ? .3 : -.3;
    }
    if(speedX != 0){
      if((speedX > 0 && this.hX < 0) || (speedX < 0 && this.hX > 0)) this.hX = 0;
      this.hX += speedX > 0 ? .3 : -.3;
    }

    this.x += this.hX;
    this.y += this.hY;

    this.set();
  }

  set() {
    createjs.Tween.get(this.container)
      .to({
        x: this.x,
        y: this.y
      }, 1000 / game.data.packageNum)
  }
}

// class Y